﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using RStein.Posterous.API;
using RStein.PosterousReader.WP.HostServices;
using Microsoft.Phone.Controls;

namespace RStein.PosterousReader.WP.UIServices
{
  public class ViewModelResolver : IViewModelResolver
  {
    public const string VIEW_SUFFIX = "View";
    public const string VIEW_MODEL_SUFFIX = "ViewModel";
    public const string VIEW_MODELS_NAMESPACE = "RStein.PosterousReader.WP.ViewModels.";
    
    public ViewModelResolver()
    {
      PosterousApp = PosterousApplication.Current;
      NavigationService = new DefaultWPNavigationService((PhoneApplicationFrame) Application.Current.RootVisual);
    }

    static ViewModelResolver()
    {
      
    }

    public virtual object ResolveViewModel(object view)
    {
      if (view == null)
      {
        throw new ArgumentNullException("view");
      }

      Type viewType = view.GetType();

      if (!IsView(viewType))
      {
        throw new ArgumentException("view", "Invalid view");
      }

    
      string viewMOdelTypeName = getViewModelName(viewType);

      Type viewModelType = Type.GetType(viewMOdelTypeName);
      
      if (viewModelType == null)
      {
        return null;
      }
      
      var viewModelConstructor  = viewModelType.GetConstructor(new [] {typeof(IPosterousApplication), typeof(INavigationService)});

      if (viewModelConstructor == null)
      {
        throw new ArgumentException("view", "Invalid view-model combination");
      }

      var viewModel = viewModelConstructor.Invoke(new Object[] {PosterousApp, NavigationService});
      return viewModel;
    }

    private static bool IsView(Type viewType)
    {
      return viewType.Name.EndsWith(VIEW_SUFFIX, StringComparison.OrdinalIgnoreCase);
    }
    
    private static string getViewModelName(Type viewType)
    {
          int typeNameLength = viewType.Name.Length;
          string viewNameWithoutSuffix = viewType.Name.Substring(0, typeNameLength - (VIEW_SUFFIX.Length));
          string viewModelName = String.Concat(VIEW_MODELS_NAMESPACE, viewNameWithoutSuffix, VIEW_MODEL_SUFFIX);
          return viewModelName;
    }

    public INavigationService NavigationService
    {
      get;
      set;
    }

    public IPosterousApplication PosterousApp
    {
      get;
      set;
    }


    public virtual bool IsView(object viewCandidate)
    {
      if (viewCandidate == null)
      {
        throw new ArgumentNullException("viewCandidate");
      }
      
      return IsView(viewCandidate.GetType()); 
    }
  }
}
